Skip to content

Conversation

@j-piasecki
Copy link
Member

Description

This PR allows users to override whether a particular GestureHandlerRootView is enabled or not. By default, only the topmost root view would be active, allowing all gestures to interact with each other.

The problem with that approach is that if any of the native views underneath calledrequestDisallowInterceptTouchEvent, all gestures would be canceled. It comes from the fact that requestDisallowInterceptTouchEvent calls are propagated up the view hierarchy and we expect GestureHandlerRootView to be relatively close to the top.

The simple solution would be to add another root view underneath the view that may call requestDisallowInterceptTouchEvent to prevent gestures from being canceled, this, however, resulted in two problems:

  • the inner root view would not be enabled
  • after adding the option to enable it manually, both root views would start handling the event, resulting in duplicated event streams

I've fixed the second problem by adding checks at the beginning of extractGestureHandlers and traverseWithPointerEvents to ensure that we're not extracting gestures attached under another enabled root view.

This allows for solving the problem described in #2383.

Test plan

Tested on the reproduction from #2383

Copy link
Contributor

@m-bert m-bert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lpatrun
Copy link

lpatrun commented Mar 21, 2024

Can we expect this to be merged? It's approved after all
🙈

@j-piasecki
Copy link
Member Author

Actually, I'm not sure if this is the best solution to this problem. I'll try to get back to it in the near future to see if I can find other approaches to this.

@lpatrun
Copy link

lpatrun commented Mar 21, 2024

@j-piasecki thank you for the quick response

@javaing
Copy link

javaing commented Jun 27, 2024

Hi still has same problem in 2024, any suggestions? thanks

@justinkx
Copy link

@j-piasecki Issue is still reproducible in Nested Tabs with "@react-navigation/material-top-tabs": "7.3.7"
Do you think this approach is ready to be merged ?

@j-piasecki j-piasecki force-pushed the @jpiasecki/root-view-always-active branch from b9f236c to ad3f731 Compare October 21, 2025 11:34
@j-piasecki j-piasecki requested a review from m-bert October 21, 2025 11:34
@j-piasecki
Copy link
Member Author

As I mentioned in the previous message, this is more of a workaround than a solution, hence I changed the prop name with an unstable_ prefix. The proper fix will require some under-the-hood changes (which we are actively working on) and removal of APIs that will not make use of the new implementation.

Given that it will take time to make it possible to implement a proper fix, I think we can merge this as a temporary solution. Keep in mind that this API will be removed in the future, and will cause unexpected behavior when trying to reference gestures attached under different root views in gesture relations.

Copy link
Contributor

@m-bert m-bert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I trust you 🫣

@j-piasecki j-piasecki merged commit 36e6153 into main Oct 22, 2025
6 checks passed
@j-piasecki j-piasecki deleted the @jpiasecki/root-view-always-active branch October 22, 2025 15:52
j-piasecki added a commit that referenced this pull request Oct 27, 2025
This PR allows users to override whether a particular
`GestureHandlerRootView` is enabled or not. By default, only the topmost
root view would be active, allowing all gestures to interact with each
other.

The problem with that approach is that if any of the native views
underneath called`requestDisallowInterceptTouchEvent`, all gestures
would be canceled. It comes from the fact that
`requestDisallowInterceptTouchEvent` calls are propagated up the view
hierarchy and we expect `GestureHandlerRootView` to be relatively close
to the top.

The simple solution would be to add another root view underneath the
view that may call `requestDisallowInterceptTouchEvent` to prevent
gestures from being canceled, this, however, resulted in two problems:
- the inner root view would not be enabled
- after adding the option to enable it manually, both root views would
start handling the event, resulting in duplicated event streams

I've fixed the second problem by adding checks at the beginning of
`extractGestureHandlers` and `traverseWithPointerEvents` to ensure that
we're not extracting gestures attached under another enabled root view.

This allows for solving the problem described in
#2383.

Tested on the reproduction from
#2383
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants